package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/rw555/fdsmastergo/pkg/device/serial"
	"gitee.com/rw555/fdsmastergo/pkg/keypad"
	"gitee.com/rw555/fdsmastergo/pkg/logger"
	"go.uber.org/zap"
)

func main() {
	// 解析命令行参数
	var (
		port     = flag.String("port", "/dev/ttyACM0", "串口设备路径")
		baudRate = flag.Int("baud", 115200, "波特率")
		debug    = flag.Bool("debug", true, "启用调试日志")
		example  = flag.String("example", "basic", "运行示例类型: basic, events, ble, all")
	)
	flag.Parse()

	// 配置日志 - logger包会自动初始化
	defer logger.Sync()

	logger.SystemInfo("串口设备测试工具启动",
		zap.String("port", *port),
		zap.Int("baudRate", *baudRate),
		zap.Bool("debug", *debug),
		zap.String("example", *example))

	// 创建配置
	config := serial.NewDefaultConfig()
	config.Port = *port
	config.BaudRate = *baudRate
	config.EnableDebugLog = *debug

	// 创建设备
	device, err := serial.NewSerialDevice(config)
	if err != nil {
		logger.SystemError("创建串口设备失败", zap.Error(err))
		os.Exit(1)
	}

	// 设置信号处理
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	// 设置事件回调
	setupEventHandlers(device)

	// 连接设备
	if err := device.Connect(); err != nil {
		logger.SystemError("连接设备失败", zap.Error(err))
		os.Exit(1)
	}
	defer device.Disconnect()

	// 等待设备就绪
	for i := 0; i < 10; i++ {
		if device.IsReady() {
			logger.SystemInfo("设备已就绪")
			break
		}
		time.Sleep(time.Second)
		if i == 9 {
			logger.SystemError("设备未能就绪，退出")
			os.Exit(1)
		}
	}

	// 根据示例类型运行测试
	switch *example {
	case "basic":
		if err := runBasicTest(device); err != nil {
			logger.SystemError("基本功能测试失败", zap.Error(err))
			os.Exit(1)
		}
	case "events":
		runEventTest(device, sigChan)
	case "ble":
		if err := runBLETest(device); err != nil {
			logger.SystemError("BLE功能测试失败", zap.Error(err))
			os.Exit(1)
		}
	case "all":
		if err := runBasicTest(device); err != nil {
			logger.SystemError("基本功能测试失败", zap.Error(err))
			os.Exit(1)
		}
		if err := runBLETest(device); err != nil {
			logger.SystemError("BLE功能测试失败", zap.Error(err))
			os.Exit(1)
		}
		runEventTest(device, sigChan)
	default:
		logger.SystemError("未知的示例类型", zap.String("example", *example))
		os.Exit(1)
	}
}

// setupEventHandlers 设置事件处理器
func setupEventHandlers(device *serial.SerialDevice) {
	// 按键事件处理
	device.SetKeyEventCallback(func(event serial.KeypadEvent) {
		logger.SystemInfo("🎮 按键事件",
			zap.String("key", event.Key.String()),
			zap.String("type", event.Type.String()),
			zap.Time("timestamp", event.Timestamp))

		// 自动响应按键事件
		switch event.Type {
		case serial.KeypadEventTypePress:
			handleKeyPress(device, event.Key)
		case serial.KeypadEventTypeLongPress:
			handleKeyLongPress(device, event.Key)
		}
	})

	// BLE事件处理
	device.SetBLEEventCallback(func(results serial.BLEScanResults) {
		logger.SystemInfo("📡 BLE扫描结果",
			zap.Int64("timestamp", results.Timestamp),
			zap.Int("deviceCount", len(results.Devices)))

		for i, dev := range results.Devices {
			logger.SystemInfo("📱 BLE设备",
				zap.Int("index", i+1),
				zap.String("mac", dev.MAC),
				zap.String("name", dev.Name),
				zap.Int("rssi", dev.RSSI))
		}
	})

	// 状态变化处理
	device.SetStatusChangeCallback(func(key string, value interface{}) {
		logger.SystemDebug("🔄 状态变化",
			zap.String("key", key),
			zap.Any("value", value))
	})
}

// handleKeyPress 处理按键按下事件
func handleKeyPress(device *serial.SerialDevice, key keypad.Key) {
	switch key {
	case keypad.KeyF1:
		logger.SystemInfo("执行：开启水泵")
		if err := device.OpenPump(); err != nil {
			logger.SystemError("开启水泵失败", zap.Error(err))
		}
	case keypad.KeyF2:
		logger.SystemInfo("执行：关闭水泵")
		if err := device.ClosePump(); err != nil {
			logger.SystemError("关闭水泵失败", zap.Error(err))
		}
	case keypad.KeyF3:
		logger.SystemInfo("执行：开启加热器1")
		if err := device.OpenHeater1(); err != nil {
			logger.SystemError("开启加热器1失败", zap.Error(err))
		}
	case keypad.KeyMenu:
		logger.SystemInfo("执行：关闭加热器1")
		if err := device.CloseHeater1(); err != nil {
			logger.SystemError("关闭加热器1失败", zap.Error(err))
		}
	default:
		logger.SystemDebug("未定义的按键操作", zap.String("key", key.String()))
	}
}

// handleKeyLongPress 处理按键长按事件
func handleKeyLongPress(device *serial.SerialDevice, key keypad.Key) {
	switch key {
	case keypad.KeyF1:
		logger.SystemInfo("执行：设置水泵功率100%")
		if err := device.SetPumpPower(100); err != nil {
			logger.SystemError("设置水泵功率失败", zap.Error(err))
		}
	case keypad.KeyF2:
		logger.SystemInfo("执行：设置水泵功率50%")
		if err := device.SetPumpPower(50); err != nil {
			logger.SystemError("设置水泵功率失败", zap.Error(err))
		}
	case keypad.KeyF3:
		logger.SystemInfo("执行：开启加热器2")
		if err := device.OpenHeater2(); err != nil {
			logger.SystemError("开启加热器2失败", zap.Error(err))
		}
	case keypad.KeyMenu:
		logger.SystemInfo("执行：关闭加热器2")
		if err := device.CloseHeater2(); err != nil {
			logger.SystemError("关闭加热器2失败", zap.Error(err))
		}
	}
}

// runBasicTest 运行基本功能测试
func runBasicTest(device *serial.SerialDevice) error {
	logger.SystemInfo("🔧 开始基本功能测试...")

	tests := []struct {
		name string
		test func() error
	}{
		{"00001 水泵开启", func() error { return device.OpenPump() }},
		{"00002 水泵状态检查", func() error {
			running, err := device.PumpIsRunning()
			if err != nil {
				return err
			}
			logger.SystemInfo("水泵状态", zap.Bool("running", running))
			return nil
		}},
		{"00003 设置水泵功率75%", func() error { return device.SetPumpPower(75) }},
		{"00004 获取水泵功率", func() error {
			power, err := device.GetPumpPower()
			if err != nil {
				return err
			}
			logger.SystemInfo("当前水泵功率", zap.Int("power", power))
			return nil
		}},
		{"00005 水泵关闭", func() error { return device.ClosePump() }},
		{"00006 加热器1开启", func() error { return device.OpenHeater1() }},
		{"00007 加热器1状态检查", func() error {
			open, err := device.IsHeater1Open()
			if err != nil {
				return err
			}
			logger.SystemInfo("加热器1状态", zap.Bool("open", open))
			return nil
		}},
		{"00008 加热器1关闭", func() error { return device.CloseHeater1() }},
		{"00009 读取温度", func() error {
			temp, err := device.GetTemp()
			if err != nil {
				logger.SystemError("读取温度失败", zap.Error(err))
				return err
			}
			logger.SystemInfo("当前温度", zap.Int("temperature", temp))
			return nil
		}},
		{"00010 设置LED字符串", func() error { return device.SetLEDString("1234", 0, 5, true) }},
		{"00011 获取LED字符串", func() error {
			text, dots, brightness, enable := device.GetLEDParams()
			logger.SystemInfo("当前LED字符串", zap.String("text", text), zap.Int("dots", dots), zap.Int("brightness", brightness), zap.Bool("enable", enable))
			return nil
		}},
	}

	for _, test := range tests {

		logger.SystemInfo("执行测试", zap.String("name", test.name))
		if err := test.test(); err != nil {
			return fmt.Errorf("测试'%s'失败: %w", test.name, err)
		} else {
			logger.SystemInfo("测试完成", zap.String("name", test.name))
		}

		time.Sleep(time.Millisecond * 500) // 短暂延迟
	}

	logger.SystemInfo("✅ 基本功能测试完成")
	return nil
}

// runBLETest 运行BLE功能测试
func runBLETest(device *serial.SerialDevice) error {
	logger.SystemInfo("📡 开始BLE功能测试...")

	tests := []struct {
		name   string
		action func() error
		delay  time.Duration
	}{
		{"启动BLE扫描", func() error {
			return device.SetBLEScanning(true, "")
		}, 3 * time.Second},
		{"启动过滤扫描(HeartRate)", func() error {
			return device.SetBLEScanning(true, "HeartRate")
		}, 3 * time.Second},
		{"启动过滤扫描(Unknown)", func() error {
			return device.SetBLEScanning(true, "Unknown")
		}, 3 * time.Second},
		{"停止BLE扫描", func() error {
			return device.SetBLEScanning(false, "")
		}, 1 * time.Second},
	}

	for i, test := range tests {
		logger.SystemInfo("执行BLE测试", zap.Int("step", i+1), zap.String("name", test.name))

		if err := test.action(); err != nil {
			return fmt.Errorf("BLE测试'%s'失败: %w", test.name, err)
		}

		if test.delay > 0 {
			logger.SystemInfo("等待扫描结果...", zap.Duration("delay", test.delay))
			time.Sleep(test.delay)
		}
	}

	logger.SystemInfo("✅ BLE功能测试完成")
	return nil
}

// runEventTest 运行事件监听测试
func runEventTest(device *serial.SerialDevice, sigChan chan os.Signal) {
	logger.SystemInfo("🎯 开始事件监听测试...")
	logger.SystemInfo("按键映射:")
	logger.SystemInfo("  F1: 开启水泵 (长按: 功率100%)")
	logger.SystemInfo("  F2: 关闭水泵 (长按: 功率50%)")
	logger.SystemInfo("  F3: 开启加热器1 (长按: 开启加热器2)")
	logger.SystemInfo("  F4: 关闭加热器1 (长按: 关闭加热器2)")
	logger.SystemInfo("按Ctrl+C退出...")

	// 启动BLE扫描以接收更多事件
	if err := device.SetBLEScanning(true, ""); err != nil {
		logger.SystemWarn("启动BLE扫描失败", zap.Error(err))
	}

	// 等待退出信号
	<-sigChan
	logger.SystemInfo("收到退出信号，正在关闭...")

	// 停止BLE扫描
	device.SetBLEScanning(false, "")
}
